/**
 * @description wait notify 成员方法进行线程同步的例程
 * 
 * 故事--实验室进行数据的更新与分析
 * 助理不断测量并更新数据，分析人员 同时 对数据进行处理
 * 助理更新的数据会缓存在m_temperature,
 * 分析将助理的数据保存在自己缓存中，延时小段时间，判断自己缓存和助理缓存是否相同，
 * 程序说明：
 * 利用wait notify 和m_ready 实现更新和分析的同步
 * 两个线程公用一个具有两个同步方法的实例对象。
 * 
 * 助理操作J_Experiment, m_ready为false，执行更新操作， 此时等待集为空（wait set 不含有任何线程），更改mready为true，
 * 助理再次进入，mready为true，执行wait，该线程进入等待集，
 * 分析进入，mready为true，执行更新，修改mready 为 false 并激活等待集线程。
 * 
 * 书上解释的顺序：
 * a进入  mready 为false  数据需要更新，
 * b进入 mready 为false 数据未更新好， b执行wait 进入wait set 等待a notify将其激活
 * a更新完成，mready 为true ，激活b 
 * a 与b竞争进入，
 * 如果 a 进入，mready为true ，执行wait，进入等待集
 * 如果b 进入， mready为true ，分析数据，修改mready 为 false ，notify a
 * 
 * 思路过程， a进入 ，未完成 b进入，  a完成，a再次进入，执行wait
 * 
 * @pageNo 425
 * @author mlmoria
 * @date 2017年2月8日
 * 
 */
package No11Thread.notify;

class J_Experiment{
	private int m_temperature,m_pressure;
	private boolean m_ready=false;
	public synchronized void mb_update(int t,int p){
		System.out.println("进入更新方法内部：");
		if(m_ready){
			System.out.println("   等待数据分析完成。。。");
			try {
				wait();
			} catch (InterruptedException e) {

				e.printStackTrace();
			}
		}
		m_temperature=t;
		m_pressure=p;
		System.out.println("更新完成：温度值为"+t+"气压值为"+p);
		m_ready=true;
		notify();
	}
	
	public synchronized void mb_analyze(){
		System.out.println("进入数据分析方法内部：");
		if(!m_ready){
			System.out.println("   等待数据更新完成。。。");
			try {
				wait ();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("   继续分析数据。。。");
		}
		int t=m_temperature;
		int p=m_pressure;
		System.out.println("分析完成：温度值为"+t+",气压值为"+p);
		m_ready=false;
		notify();
		
	}
	
}

class J_Assistant extends Thread{
	J_Experiment m_data;
	public J_Assistant(J_Experiment d){
		m_data=d;
	}
	
	@Override
	public void run() {
		System.out.println("助理线程开始工作");
		int i,j,k;
		for(k=0;k<3;k++){
			i=(int)(Math.random()*1000);
			j=(int)(Math.random()*1000);
			m_data.mb_update(i, j);
		}
		
		System.out.println("助理线程结束工作");
	}
}

class J_Analyst extends Thread{
	J_Experiment m_data;
	public J_Analyst(J_Experiment d){
		m_data=d;
	}
	
	@Override
	public void run() {
	    System.out.println("分析线程开始工作");
		for(int k=0;k<3;k++){
			m_data.mb_analyze();
		}
		System.out.println("分析线程结束工作");
	    
	}
	
}

public class J_WaitNotify {

	public static void main(String[] args) {
		J_Experiment data=new J_Experiment();
		J_Assistant threadA=new J_Assistant(data);
		J_Analyst threadB=new J_Analyst(data);
		threadA.start();
		threadB.start();
		System.out.println("方法main结束");
	}

	
}
